package org.snaker.engine.springboot.configuration;

import org.snaker.engine.Completion;
import org.snaker.engine.DBAccess;
import org.snaker.engine.Expression;
import org.snaker.engine.service.IProcessService;
import org.snaker.engine.service.IQueryService;
import org.snaker.engine.service.ITaskService;
import org.snaker.engine.TaskAccessStrategy;
import org.snaker.engine.cache.CacheManager;
import org.snaker.engine.cache.memory.MemoryCacheManager;
import org.snaker.engine.service.impl.ManagerService;
import org.snaker.engine.service.impl.OrderService;
import org.snaker.engine.service.impl.ProcessService;
import org.snaker.engine.service.impl.QueryService;
import org.snaker.engine.service.impl.TaskService;
import org.snaker.engine.impl.GeneralAccessStrategy;
import org.snaker.engine.impl.GeneralCompletion;
import org.snaker.engine.impl.JuelExpression;
import org.snaker.engine.parser.ModelParser;
import org.snaker.engine.parser.NodeParserProvider;
import org.snaker.engine.parser.xml.XMLModelParser;
import org.snaker.engine.parser.xml.XmlNodeParserProvider;
import org.snaker.engine.springboot.SpringJdbcAccess;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.w3c.dom.Element;

/**
 * 代替ext.config.xml
 */
@Configuration
@AutoConfigureAfter(JdbcTemplateAutoConfiguration.class)
public class AccessConfiguration {

    @Bean
    public XmlNodeParserProvider nodeParserProvider(){
        return new XmlNodeParserProvider();
    }

    @Bean
    public Completion completion(){
        return new GeneralCompletion();
    }

    @Bean
    public Expression expression(){
        return new JuelExpression();
    }

    @Bean
    public ModelParser modelParser(NodeParserProvider<Element> nodeParserProvider){
        return new XMLModelParser(nodeParserProvider);
    }

    @Bean
    public SpringJdbcAccess springJdbcAccess(JdbcTemplate jdbcTemplate){
        return new SpringJdbcAccess(jdbcTemplate);
    }

    @Bean
    public CacheManager cacheManager(){
        return new MemoryCacheManager();
    }

    @Bean
    public ProcessService processService(ModelParser modelParser, CacheManager cacheManager, DBAccess dbAccess){
        //TODO
        ProcessService processService = new ProcessService(modelParser,dbAccess);
        processService.setCacheManager(cacheManager);
        return processService;
    }

    @Bean
    public OrderService orderService(SpringJdbcAccess springJdbcAccess, Completion completion, IQueryService queryService, ITaskService taskService){
        return new OrderService(springJdbcAccess, completion, queryService, taskService);
    }

    @Bean
    public TaskAccessStrategy accessStrategy(){
        return new GeneralAccessStrategy();
    }


    @Bean
    public TaskService taskService(SpringJdbcAccess springJdbcAccess, TaskAccessStrategy accessStrategy, IProcessService processService, Completion completion){
        return new TaskService(springJdbcAccess, accessStrategy, processService, completion);
    }

    @Bean
    public ManagerService managerService(SpringJdbcAccess springJdbcAccess){
        return new ManagerService(springJdbcAccess);
    }

    @Bean
    public QueryService queryService(SpringJdbcAccess springJdbcAccess){
        return new QueryService(springJdbcAccess);
    }
}
